package com.nanjia.boot.myflow.deliveryaddressflow.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nanjia.boot.common.enums.StockFlowEnum;
import com.nanjia.boot.myflow.deliveryaddressflow.converter.DeliveryAddressFlowConverter;
import com.nanjia.boot.myflow.deliveryaddressflow.mapper.DeliveryAddressFlowMapper;
import com.nanjia.boot.myflow.deliveryaddressflow.model.entity.DeliveryAddressFlow;
import com.nanjia.boot.myflow.deliveryaddressflow.model.form.DeliveryAddressFlowForm;
import com.nanjia.boot.myflow.deliveryaddressflow.model.query.DeliveryAddressFlowQuery;
import com.nanjia.boot.myflow.deliveryaddressflow.model.vo.DeliveryAddressFlowVO;
import com.nanjia.boot.myflow.deliveryaddressflow.service.DeliveryAddressFlowService;
import com.nanjia.boot.myflow.order.item.mapper.OrderItemMapper;
import com.nanjia.boot.myflow.order.item.model.entity.OrderItem;
import com.nanjia.boot.myflow.order.service.OrderService;
import com.nanjia.boot.myflow.outboundorderdetail.model.entity.OutboundOrderDetail;
import com.nanjia.boot.myflow.outboundorderdetail.service.OutboundOrderDetailService;
import com.nanjia.boot.outboundorder.model.entity.OutboundOrder;
import com.nanjia.boot.outboundorder.service.OutboundOrderService;
import com.nanjia.boot.outboundorderview.model.entity.OutboundOrderView;
import com.nanjia.boot.outboundorderview.service.OutboundOrderViewService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 收货/收票信息流水服务实现类
 *
 * @author 周洋
 * @since 2025-07-29 16:44
 */
@Service
@RequiredArgsConstructor
public class DeliveryAddressFlowServiceImpl extends ServiceImpl<DeliveryAddressFlowMapper, DeliveryAddressFlow> implements DeliveryAddressFlowService {

    private final DeliveryAddressFlowConverter deliveryAddressFlowConverter;

    private final OrderService orderService;
    private final OutboundOrderService outboundOrderService;
    private final OutboundOrderViewService outboundOrderViewService;
    private final OutboundOrderDetailService outboundOrderDetailService;
    private final OrderItemMapper orderItemMapper;

    /**
     * 获取收货/收票信息流水分页列表
     *
     * @param queryParams 查询参数
     * @return {@link IPage<DeliveryAddressFlowVO>} 收货/收票信息流水分页列表
     */
    @Override
    public IPage<DeliveryAddressFlowVO> getDeliveryAddressFlowPage(DeliveryAddressFlowQuery queryParams) {
        Page<DeliveryAddressFlowVO> pageVO = this.baseMapper.getDeliveryAddressFlowPage(
                new Page<>(queryParams.getPageNum(), queryParams.getPageSize()),
                queryParams
        );
        return pageVO;
    }

    /**
     * 获取收货/收票信息流水表单数据
     *
     * @param id 收货/收票信息流水ID
     * @return 收货/收票信息流水表单数据
     */
    @Override
    public DeliveryAddressFlowForm getDeliveryAddressFlowFormData(Long id) {
        DeliveryAddressFlow entity = this.getById(id);
        return deliveryAddressFlowConverter.toForm(entity);
    }

    /**
     * 新增收货/收票信息流水
     *
     * @param formData 收货/收票信息流水表单对象
     * @return 是否新增成功
     */
    @Override
    public boolean saveDeliveryAddressFlow(DeliveryAddressFlowForm formData) {
        DeliveryAddressFlow entity = deliveryAddressFlowConverter.toEntity(formData);
        return this.save(entity);
    }

    /**
     * 更新收货/收票信息流水
     *
     * @param id       收货/收票信息流水ID
     * @param formData 收货/收票信息流水表单对象
     * @return 是否修改成功
     */
    @Override
    public boolean updateDeliveryAddressFlow(Long id, DeliveryAddressFlowForm formData) {
        DeliveryAddressFlow entity = deliveryAddressFlowConverter.toEntity(formData);
        return this.updateById(entity);
    }

    /**
     * 删除收货/收票信息流水
     *
     * @param ids 收货/收票信息流水ID，多个以英文逗号(,)分割
     * @return 是否删除成功
     */
    @Override
    public boolean deleteDeliveryAddressFlows(String ids) {
        Assert.isTrue(StrUtil.isNotBlank(ids), "删除的收货/收票信息流水数据为空");
        // 逻辑删除
        List<Long> idList = Arrays.stream(ids.split(","))
                .map(Long::parseLong)
                .toList();
        return this.removeByIds(idList);
    }


    @Override
    public List<DeliveryAddressFlowVO> getDAFlowList(List<Long> orderIds) {
        Set<Long> daf0Ids = new HashSet<>();
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>().in(OrderItem::getOrderId, orderIds));
        if (CollectionUtils.isNotEmpty(orderItemList)) {
            orderItemList.forEach(orderItem -> {
                daf0Ids.add(orderItem.getDaf0Id());
                daf0Ids.add(orderItem.getDaf1Id());
            });
        }

        List<OutboundOrderView> outboundOrderViewList = outboundOrderViewService
                .list(new LambdaQueryWrapper<OutboundOrderView>()
                        .in(OutboundOrderView::getExternalId, orderIds)
                        .eq(OutboundOrderView::getExternalType, StockFlowEnum.SFE21.getLabel()));
        List<OutboundOrder> outboundOrderList = new ArrayList<>();
        List<OutboundOrderDetail> outboundOrderDetailList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(outboundOrderViewList)) {
            outboundOrderList = outboundOrderService
                    .list(new LambdaQueryWrapper<OutboundOrder>()
                            .in(OutboundOrder::getId, outboundOrderViewList.stream().map(OutboundOrderView::getOutboundOrderId).collect(Collectors.toList())));

            outboundOrderDetailList = outboundOrderDetailService
                    .list(new LambdaQueryWrapper<OutboundOrderDetail>()
                            .in(OutboundOrderDetail::getOutboundOrderId, outboundOrderList.stream().map(OutboundOrder::getId).collect(Collectors.toList())));

            for (OutboundOrder order : outboundOrderList) {
                daf0Ids.add(order.getDaf0Id());
                daf0Ids.add(order.getDaf1Id());
            }
        }


        List<DeliveryAddressFlow> deliveryAddressFlowList = this.list(new LambdaQueryWrapper<DeliveryAddressFlow>().in(DeliveryAddressFlow::getId, daf0Ids));


        List<DeliveryAddressFlowVO> voList = deliveryAddressFlowList.stream().map(deliveryAddressFlowConverter::toVO).collect(Collectors.toList());
        for (DeliveryAddressFlowVO deliveryAddressFlowVO : voList) {
            for (OrderItem orderItem : orderItemList) {
                if (deliveryAddressFlowVO.getId().longValue() == orderItem.getDaf0Id().longValue() || deliveryAddressFlowVO.getId().longValue() == orderItem.getDaf1Id().longValue()) {
                    deliveryAddressFlowVO.setOrderId(orderItem.getOrderId());
                    break;
                }
            }
        }
        for (DeliveryAddressFlowVO deliveryAddressFlowVO : voList) {
            if (CollectionUtils.isNotEmpty(outboundOrderList) && CollectionUtils.isNotEmpty(outboundOrderDetailList)) {
                for (OutboundOrder outboundOrder : outboundOrderList) {
                    if (deliveryAddressFlowVO.getId().longValue() == outboundOrder.getDaf0Id().longValue() || deliveryAddressFlowVO.getId().longValue() == outboundOrder.getDaf1Id().longValue()) {
                        for (OutboundOrderView outboundOrderView : outboundOrderViewList) {
                            if (outboundOrderView.getOutboundOrderId().longValue() == outboundOrder.getId().longValue()) {
                                for (Long orderId : orderIds) {
                                    if (orderId.longValue() == outboundOrderView.getExternalId().longValue()) {
                                        deliveryAddressFlowVO.setOrderId(orderId);
                                        for (OutboundOrderDetail outboundOrderDetail : outboundOrderDetailList) {
                                            if (outboundOrderDetail.getOutboundOrderId().longValue() == outboundOrder.getId().longValue()) {
                                                deliveryAddressFlowVO.setEms(outboundOrderDetail.getEms());
                                                deliveryAddressFlowVO.setEmsstatus(outboundOrderDetail.getStatus());
                                                deliveryAddressFlowVO.setEmsnumber(outboundOrderDetail.getEmsnumber());
                                                break;
                                            }
                                        }
                                        break;
                                    }
                                }
                                break;
                            }
                        }
                        break;
                    }
                }
            }

        }
        return voList;
    }
}
